package com.ttc.mBackup.BackupImages;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import android.os.AsyncTask;
import android.util.Log;
import android.widget.ProgressBar;
import android.widget.TextView;

public class RestoreImages extends AsyncTask<Void, String, String> {
	
	public final static int BACKUP_MERGE = 0;
	public final static int BACKUP_OVERRIDE = 1;
	
	final String TAG = "mediastore";
	String zipFilePath;
	String destinationPath;
	
	private TextView txtStatus;
	private TextView txtPercent;
	private ProgressBar progress;
	private int zipentries;
	private int backupType;
	private boolean isFinished = false;
	
	public boolean isFinished() {
		return isFinished;
	}

	public void setFinished(boolean isFinished) {
		this.isFinished = isFinished;
	}

	public RestoreImages(String zipFilePath, String destinationPath,
			TextView txtStatus, TextView txtPercent, ProgressBar progress, int backupType) {
		super();
		this.zipFilePath = zipFilePath;
		this.destinationPath = destinationPath;
		this.txtStatus = txtStatus;
		this.txtPercent = txtPercent;
		this.progress = progress;
		this.backupType = backupType;
	}

	@SuppressWarnings("unchecked")
	@Override
	protected String doInBackground(Void... params) {
		String result="";
		File archive = new File(zipFilePath);
		try {
			ZipFile zipfile = new ZipFile(archive);
			zipentries = zipfile.size();
			Log.i("mediastore", String.valueOf(zipentries));
			this.progress.setMax(zipentries);
			int i=-1;
			for (Enumeration e = zipfile.entries(); e.hasMoreElements();) {
				i++;
				Log.i("mediastore", String.valueOf(i));
				ZipEntry entry = (ZipEntry) e.nextElement();
				
				if(backupType == BACKUP_MERGE){
					File outputFile = new File(destinationPath, entry.getName());
					if(!outputFile.exists())
						unzipEntry(zipfile, entry, destinationPath);
				}
				else 
					unzipEntry(zipfile, entry, destinationPath);
				
				//update process
				String[] str = new String[] { "Extracting: " + entry.getName(),
						String.valueOf(i+1) };
				publishProgress(str);
				Log.v("mediastore", str[0]);
				
			}
			result = "Finished";
		} catch (Exception e) {
			Log.e(TAG, "Error while extracting file " + archive, e);
			result =  "Error";
		}

		return result;
	}

	@Override
	protected void onPostExecute(String result) {
		isFinished = true;
		txtStatus.setText(result);
		super.onPostExecute(result);
	}

	@Override
	protected void onProgressUpdate(String... values) {
		int progr = Integer.parseInt(values[1]);
		int percent =(int) Math.round(((progr*1.0)/zipentries) *100) ;
		
		txtStatus.setText(values[0]);
		txtPercent.setText(String.valueOf(percent)+"%");
		
		progress.setProgress(progr);
		super.onProgressUpdate(values);
	}

	private void unzipEntry(ZipFile zipfile, ZipEntry entry, String outputDir)
			throws IOException {

		if (entry.isDirectory()) {
			createDir(new File(outputDir, entry.getName()));
			return;
		}

		File outputFile = new File(outputDir, entry.getName());
		
		
		if (!outputFile.getParentFile().exists()) {
			createDir(outputFile.getParentFile());
		}

		Log.v(TAG, "Extracting: " + entry);
		BufferedInputStream inputStream = new BufferedInputStream(zipfile
				.getInputStream(entry));
		BufferedOutputStream outputStream = new BufferedOutputStream(
				new FileOutputStream(outputFile));

		try {
			copy(inputStream, outputStream);
		} finally {
			outputStream.close();
			inputStream.close();
		}
	}

	private void createDir(File dir) {
		if (dir.exists()) {
			return;
		}
		Log.v(TAG, "Creating dir " + dir.getName());
		if (!dir.mkdirs()) {
			throw new RuntimeException("Can not create dir " + dir);
		}
	}

	private void copy(InputStream in, OutputStream out) throws IOException {
		byte[] b = new byte[1024];
		int read;
		while ((read = in.read(b)) != -1) {
			out.write(b, 0, read);
		}
	}

}
